import abc
from panda3d.core import Vec3, VBase3, NodePath
import __builtin__


class Unit(object):

    def __init__(self, unit_object, speed, name, radius, hp, worth, upgrades, cost):
        self.unit_object = NodePath("ModelContainer")
        self.model = unit_object
        unit_object.reparentTo(self.unit_object)
        self.speed = speed
        self.name = name
        self.upgrades = upgrades
        self.cost = cost
        self.amount = 1
        self.radius = radius
        self.moving = False

        self.destinations = []
        self.destination = Vec3(0, 0, 0)
        self.nextPos = Vec3(0,0,0)
        self.target = (0,0)
        self.dir = Vec3(0,0,0)
        self.movetime = 0.0
        self.manager = __builtin__.base.gamestatemanager.getState("RunningSession").unitmanager
        self.BROADCAST_INTERVAL = __builtin__.base.gamestatemanager.getState("RunningSession").BROADCAST_INTERVAL
        self.hp = hp
        self.worth = worth

    def reparentTo(self, parent):
        self.unit_object.reparentTo(parent)

    def detach_node(self):
        self.unit_object.detach_node()

    def update(self, dt):
        if self.movetime <0:
            self.movetime = 0
            self.moving = False
            #self.model.stop()
        if self.movetime > 0:
            self.movetowards(self.dir * dt/self.BROADCAST_INTERVAL)
            self.movetime -= dt



    def move(self, tpf):
        pos = self.unit_object.getPos(__builtin__.render)
        direct = -pos + self.destination
        VBase3.normalize(direct)
        direct *= (self.speed*tpf*0.5)
        self.unit_object.setPos(__builtin__.render, direct + pos)
        return

    def get_name(self):
        return self.name

    def queue_destination(self, x, y):
        self.destinations.append(Vec3(x, y, 0))

    def getposition(self):
        return self.unit_object.getPos(__builtin__.render)

    def movetowards(self, dir):
        pos = self.unit_object.getPos(__builtin__.render)
        self.unit_object.setPos(__builtin__.render, pos + dir)

    def setPos(self, pos):
        self.unit_object.setPos(__builtin__.render, pos)

    def setNextPos(self, pos):
        self.nextPos = pos
        cpos = self.getposition()
        dis = pos - cpos
        quaddis = (dis.x*dis.x)+(dis.y*dis.y)
        if quaddis > 0.01:
            self.dir = dis
            self.reface()
            self.movetime = self.BROADCAST_INTERVAL
            if not self.moving:
                self.moving = True
                #self.model.loop("move")

    def set_destination(self, x, y):
        self.destination = Vec3(x, y, 0)
        self.model.headsUp(__builtin__.render, x,y,0)
        self.model.setH(self.model.getH()+90)

    def reface(self):
        if self.target[0]+self.target[1] == 0:
            self.model.headsUp(__builtin__.render, self.nextPos.x, self.nextPos.y, 0)
            self.model.setH(self.model.getH()+90)
        else:
            self.model.headsUp(__builtin__.render, self.target[0], self.target[1], 0)
            self.model.setH(self.model.getH()+90)

    def face(self, pos):
        self.target = pos
        self.model.headsUp(__builtin__.render, pos[0], pos[1], 0)
        self.model.setH(self.model.getH()+90)

    def damage(self, dmg):
        self.hp -= dmg

    def remove_node(self):
        self.model.remove_node()
        del self.model
        self.unit_object.remove_node()
        del self.unit_object
